Part 4. 에러 처리

58개 중 3개. 에러를 처리하지 않거나 불충분하게 처리하여, 에러정보에 중요정보(시스템 정보 등)가 포함될 때 발생한다. 관통 질문: 실패했을 때 무엇을 할지가 코드에 적혀 있는가? 그리고 그 실패 내용을 사용자에게도 보여주고 있는가? 가이드 원문 순서 그대로 진행.


1. 오류 메시지 통한 정보 노출 CWE-209

신뢰 경계: 환경변수·내부 경로 → 그대로 → 사용자에게 보이는 오류 메시지 ⚠️ 상세 에러는 로그(내부)로, 사용자(외부)에게는 단일하고 무의미한 메시지로. 정보 분리가 원칙이다.

공격 시나리오: 공격자는 노출된 경로·환경변수·실패 지점 정보를 조합해 시스템 환경을 정밀하게 수집하고 다음 공격의 정확도를 크게 높인다.

❌ Bad

char* path = getenv("MYPATH");
fprintf(stderr, path);              /* 환경변수 경로를 그대로 노출 */

✅ Good

char* path = getenv("MYPATH");
/* 사용자에게는 최대한 간단하게, 상세 정보는 내부 로그로만 기록 */

치환 규칙: 예외 상황은 내부에서 처리하고 사용자에게는 일반화된 단일 메시지만 노출, 상세 내용은 접근 통제된 로그로 분리.


2. 오류상황 대응 부재 CWE-390

신뢰 경계: (해당 없음 — 처리 누락 자체가 결함) ⚠️ 빈 if 블록은 “검사했다”가 아니라 “오류를 은폐했다”는 뜻이다.

공격 시나리오: 오류가 발생할 수 있는 부분을 검사는 했지만 아무런 예외처리를 하지 않으면, 오류가 묻혀 잘못된 상태 위에서 이후 로직이 계속 수행되어 데이터 손상이나 보안 검사 우회로 이어진다.

❌ Bad

if (fputs("string", stdout) == EOF)
{
    /* do nothing */             /* 검사는 하지만 아무 조치도 없음 */
}

✅ Good

if (fputs("string", stdout) == EOF)
{
    printLine("fputs failed!");
    exit(1);                     /* 실제 조치: 로그 기록 · 복구 · 종료 */
}

치환 규칙: 오류 검사 블록에는 반드시 실제 조치(로그·복구·종료)를 넣는다. 빈 오류 처리 블록은 코드 리뷰·정적분석 금지 항목으로 다룬다.


3. 적절하지 않은 예외처리 CWE-754

신뢰 경계: fgets() 실패(널 종료 미보장) → 반환값 검사 없이 → strcpy() 로 이어짐 ⚠️ 반환값은 반드시 읽고, 실패했을 때 무엇을 할지까지 코드에 적혀 있어야 예외처리다.

공격 시나리오: fgets() 가 중간에 실패해 버퍼가 널로 끝나지 않으면 이어지는 strcpy() 에서 버퍼 오버플로우가 발생한다.

❌ Bad

char fromBuf[10], toBuf[10];
fgets(fromBuf, 10, stdin);        /* 반환값을 검사하지 않는다 */
strcpy(toBuf, fromBuf);           /* 에러로 '\0' 종료가 안 되면 오버플로우 */

✅ Good

char *retBuf = fgets(fromBuf, 10, stdin);
if (retBuf != fromBuf)            /* 함수호출 이후 결과 값을 비교 */
{
    println("에러");
    return;
}
strcpy(toBuf, fromBuf);

치환 규칙: 값을 반환하는 모든 함수의 결과를 검사하고, 광범위한 예외처리 대신 상황별 구체적 처리, 실패 시 기본값 초기화 등 복구 경로를 마련한다.


Part 4 미니 체크리스트

  • 사용자에게 보이는 오류 메시지에 경로·환경변수·스택 정보가 섞여 있는가
  • if (... == 에러) { } 처럼 본문이 빈 오류 처리 블록이 있는가
  • 반환값을 검사하지 않고 바로 다음 연산에 쓰는 함수 호출이 있는가(fgets→strcpy 등)
  • 실패 시 복구 경로(기본값·재시도·중단)가 코드에 명시되어 있는가

관련 노트